package end.controller;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import end.bean.shiro.Manager;
import end.bean.shiro.Resource;
import end.constant.Const;
import end.handler.aop.log.EnumLog;
import end.handler.aop.log.SystemControllerLog;
import end.ser.ManagerSER;
import end.ser.ResourceSER;
import end.util.AESUtils;
import end.util.MD5Utils;
import end.util.RightsHelper;
import end.util.VerifyCode;

/**
 * 
 * ManagerForController.java 2016-6-24
 * 
 * Copyright zhaocj Inc. All rights reserved. Love Me Like Love Justin Bieber
 */
@Controller
@RequestMapping("/manager")
public class ManagerForController {
	private final static Logger log = LogManager
			.getLogger(ManagerForController.class);
	@Autowired
	public ResourceSER<Resource> resourceSER;

	public ResourceSER<Resource> getResourceSER() {
		return resourceSER;
	}

	public void setResourceSER(ResourceSER<Resource> resourceSER) {
		this.resourceSER = resourceSER;
	}

	@Autowired
	private ManagerSER<Manager> managerSER;

	public ManagerSER<Manager> getManagerSER() {
		return managerSER;
	}

	public void setManagerSER(ManagerSER<Manager> managerSER) {
		this.managerSER = managerSER;
	}

	@RequestMapping(value = "/query", method = { RequestMethod.POST })
	public @ResponseBody
	boolean queryManagerByOption(
			@RequestParam(value = "code", required = true) String code,
			@RequestParam(value = "password", required = true) String password,
			HttpSession session) throws Exception {
		try {
			String userPassword = AESUtils.aesDecrypt(password);
			SecurityUtils.getSubject().login(
					new UsernamePasswordToken(code, userPassword));
			Integer[] rightsId = resourceSER.queryMenuRightsByManager(code);
			if (rightsId.length == 0) {
				session.setAttribute("menuList", null);
			} else {
				List<Resource> resources = resourceSER.queryMenuResources();
				for (Resource resource : resources) {
					List<Resource> children = resource.getChildren();
					for (Resource resource2 : children) {
						resource2.setHasResource(RightsHelper.testRights(
								RightsHelper.sumRights(rightsId),
								resource2.getId()));
					}
					resource.setHasResource(RightsHelper.testRights(
							RightsHelper.sumRights(rightsId), resource.getId()));
				}
				session.setAttribute("menuList", resources);
			}
		} catch (AuthenticationException e) {
			log.error("用户名或密码错误");
			return false;
		}
		/*
		 * Manager manager = managerSER.selectByPrimaryKey("manager5");
		 * log.info(JsonUtil.toJson(manager)+"--------------已登录"); if (manager
		 * == null) { return false; } else {
		 * session.setAttribute(Const.SESSION_USER, manager);
		 * 
		 * List<Function> functions =
		 * functionSER.getFunctionRightsByUserId(manager.getId()); String string
		 * = ""; for (Function function : functions) { string =
		 * string+function.getUrl(); }
		 * 
		 * log.info("用户可使用的url标示字符串"+string);
		 * session.setAttribute(Const.SESSION_USER_RIGHTS, string);
		 * 
		 * String today = DateUtils.getDate("yyyy-MM-dd");
		 * 
		 * JedisUtil.activeUsers("daily_active_users:" + today,
		 * manager.getId());
		 */
		return true;
	}

	@RequestMapping("/modifyPass")
	public @ResponseBody
	boolean modifyPass(String newPass, HttpSession session) throws Exception {
		Manager manager = (Manager) session.getAttribute(Const.SESSION_USER);
		String saltCode = MD5Utils.getRandomString(8);
		manager.setSalt(AESUtils.aesEncrypt(saltCode, AESUtils.SALTKEY));
		manager.setPassword(MD5Utils.GetSaltCode(AESUtils.aesDecrypt(newPass),
				saltCode));
		managerSER.modifyPass(manager);
		SecurityUtils.getSubject().logout();
		return true;
	}

	@RequestMapping("/insert")
	@SystemControllerLog(description = "添加一个管理员", logType = EnumLog.managerTYPE, logOperState = EnumLog.insertManagerLOG, clazz = Manager.class)
	public @ResponseBody
	boolean insertManager(Manager manager) throws Exception {
		// 对管理员数据进行加盐操作
		String saltCode = MD5Utils.getRandomString(8);
		manager.setSalt(AESUtils.aesEncrypt(saltCode, AESUtils.SALTKEY));
		manager.setPassword(MD5Utils.GetSaltCode(manager.getPassword(),
				saltCode));
		managerSER.insert(manager);
		return true;
	}

	@RequestMapping("/isManagerCodeAlreadyUsed")
	public @ResponseBody
	boolean isManagerCodeAlreadyUsed(Manager manager) {
		return managerSER.isManagerCodeAlreadyUsed(manager);
	}

	@RequestMapping("/modifyManager")
	@SystemControllerLog(description = "修改管理员信息", logType = EnumLog.managerTYPE, logOperState = EnumLog.updateManagerLOG, clazz = Manager.class)
	public @ResponseBody
	boolean modifyManagerByID(Manager manager) throws Exception {
		// 如果密码为空 则认为密码不用修改
		if (manager.getPassword() != null && !manager.getPassword().equals("")) {
			String saltCode = MD5Utils.getRandomString(8);
			String saltStr = AESUtils.aesEncrypt(saltCode, AESUtils.SALTKEY);
			String codePassword = MD5Utils.GetSaltCode(
					AESUtils.aesDecrypt(manager.getPassword()), saltCode);
			manager.setSalt(saltStr);
			manager.setPassword(codePassword);
		}
		return managerSER.modifyManager(manager);
	}

	@RequestMapping("/drop")
	@SystemControllerLog(description = "删除管理员", logType = EnumLog.managerTYPE, logOperState = EnumLog.deleteManagerLOG, clazz = Manager.class)
	public @ResponseBody
	boolean dropManagers(Integer[] dropID, Manager manager) throws Exception {
		managerSER.deleteByPrimaryKey(dropID);
		return true;
	}

	@RequestMapping("/queryManagersByPage")
	public @ResponseBody
	Map<String, Object> queryManagersByPage(int page, int rows, String sort,
			String order) {
		List<Manager> managers = managerSER.queryManagersByPage(page, rows,
				sort, order);
		Map<String, Object> rets = new HashMap<String, Object>();
		rets.put("total", managers.size());
		int totalLength = managers.size();
		int toSize = totalLength - ((page - 1) * rows) <= rows ? totalLength
				: page * rows;

		rets.put("rows", managers.subList((page - 1) * rows, toSize));
		return rets;
	}

	@RequestMapping("/logout")
	public @ResponseBody
	boolean logout(HttpSession session) {
		session.setAttribute(Const.SESSION_USER, null);
		SecurityUtils.getSubject().logout();
		return true;
	}

	@RequestMapping("/identifyingCode")
	public void identifyingCode(HttpServletResponse response,
			HttpSession session) throws IOException {
		// 设置浏览器不缓存本页
		response.setDateHeader("Expires", 0);
		response.setHeader("Cache-Control",
				"no-store, no-cache, must-revalidate");
		response.addHeader("Cache-Control", "post-check=0, pre-check=0");
		response.setHeader("Pragma", "no-cache");
		// 生成验证码，写入用户session
		String verifyCode = VerifyCode.generateTextCode(
				VerifyCode.TYPE_ALL_MIXED, 8, "0oOilJI1");
		session.setAttribute(VerifyCode.VERIFY_TYPE_COMMENT, verifyCode);
		if (log.isDebugEnabled()) {
			log.debug("verifyCode=" + verifyCode);
		}
		// 输出验证码给客户端
		response.setContentType("image/jpeg");
		/*
		 * textCode 文本验证码 width 图片宽度 height 图片高度 interLine 图片中干扰线的条数
		 * randomLocation 每个字符的高低位置是否随机 backColor 图片颜色，若为null，则采用随机颜色 foreColor
		 * 字体颜色，若为null，则采用随机颜色 lineColor 干扰线颜色，若为null，则采用随机颜色
		 */
		BufferedImage bim = VerifyCode.generateImageCode(verifyCode, 125, 22,
				4, true, Color.WHITE, Color.RED, null);
		ServletOutputStream out = response.getOutputStream();
		ImageIO.write(bim, "JPEG", out);
		try {
			out.flush();
		} finally {
			out.close();
		}
	}
}
